Namespace.Use("Locale.Tree", function(ns) {
    //
    //  Global.
    //
    var g_AvailableLanguages = [];

    //
    //  Classes.
    //
    var MessageTree = Polymorphic.Create(
        [Object],
        function(tree) {
            //
            //  Public methods.
            //
            this.IsLanguageMatches = function() {
                throw "IsLanguageMatches() should be overrided."
            };
            this.HasMessage = Polymorphic.Create(
                [String],
                function(key_path) {
                    try {
                        this.GetMessage(key_path);
                    } catch (err) {
                        return false;
                    }
                    return true;
                }
            );
            this.GetMessage = Polymorphic.Create(
                [String, String],
                function(key_path, default_value) {
                    var folders = key_path.split(".");
                    var current = tree;

                    for (var i = 0; i < folders.length; ++i) {
                        var folder = folders[i];

                        //  Check the existence of the inner folder.
                        if (!((current instanceof Object) && (folder in current))) {
                            if (default_value == null) {
                                throw "No such key.";
                            }
                            return default_value;
                        }

                        //  Go to the inner folder.
                        current = current[folder];
                    }

                    //  Check the type.
                    if (current.constructor != String) {
                        if (default_value == null) {
                            throw "No such key.";
                        }
                        return default_value;
                    }

                    return current;
                },
                [String],
                function(key_path) {
                    return this.GetMessage(key_path, null);
                }
            );
        }
    );

    //  Export public APIs / classes.
    Namespace.Export(ns, "MessageTree", MessageTree);
});
